(function() {
  window.Axis = function(options) {
    var _axis = this;

    _axis._options = {
      id: "",
      title: "",
      source: {
        dynamic: {
          url: "",
          params: null,
          success: $.noop
        },
        static: {
          data: [],
          success: $.noop
        }
      },
      content: {
        top: $.noop,
        middle: $.noop,
        bottom: {
          left: $.noop,
          right: $.noop
        }
      }
    };

    _axis.settings(options);

    _axis.$obj = _axis.options.id.indexOf("#") == 0 ? $(_axis.options.id) : $("#" + _axis.options.id);
    _axis.$element = null;
    _axis.$header = null;
    _axis.$left = null;
    _axis.$right = null;
    _axis._data = null;

    _axis._func = {
      _joinHeader: function() {
        var _header = (!rapid.isEmpty(_axis.options.title) ?
                       '<div class="flowChart-header">'
                       + '<h2>' + _axis.options.title + '</h2><hr />'
                       + '</div>'
            : "");

        _axis.$header = $(_header);

        return _axis.$header;
      },
      _joinLeft: function() {
        var _left = '<div class="flowChart-left">'
                    + '<div class="dashed"></div>'
                    + '</div>';

        _axis.$left = $(_left);

        return _axis.$left;
      },
      _joinRight: function() {
        var _right = '<div class="flowChart-right"></div>';

        _axis.$right = $(_right);

        return _axis.$right;
      },
      _joinNodes: function() {
        var _content = _axis.options.content;
        var _data = _axis._data;
        var _nodes = [];

        var _decide = function(func, item, index) {
          var _res = typeof func == "function" ? ((function(item, index) {
            var res = "";

            var _t = func(item, index);
            if(typeof _t == "string") {
              res = _t;
            }

            return res;
          })(item, index)) : "";

          return _res;
        }

        for(var i = 0; i < _data.length; i++) {
          var _di = _data[i];

          var _top = _decide(_content.top, _di, i);
          var _middle = _decide(_content.middle, _di, i);
          var _bottomLeft = _decide(_content.bottom.left, _di, i);
          var _bottomRight = _decide(_content.bottom.right, _di, i);

          var _node = '<div class="oneNode">'
                      + '<div class="check">'
                      + '</div>'
                      + '<div class="tag-boder">'
                      + '<div class="tag"></div>'
                      + '</div>'
                      + '<div class="NodeDetail">'
                      + '<div class="NodeDetail-title">'
                      + _top
                      + '</div>'
                      + '<div class="NodeDetail-content">'
                      + '<p>' + _middle + '</p>'
                      + '</div>'
                      + '<div class="NodeDetail-footer">'
                      + '<div class="NodeDetail-footer-left">' + _bottomLeft + '</div>'
                      + '<div class="NodeDetail-footer-right">' + _bottomRight + '</div>'
                      + '</div>'
                      + '</div>'
                      + '</div>';

          _nodes.push(_node);
        }

        return $(_nodes.join(""));
      }
    }

    _axis.create = function() {
      var $element = $('<div class="flowChart"></div>');
      _axis.$obj.append($element);

      var _func = _axis._func;

      $element.append(_func._joinLeft())
              .append(_func._joinRight());

      _axis.$element = $element.before(_func._joinHeader());

      return _axis;
    };

    _axis.load = function(cb) {
      var _func = _axis._func;

      if(!rapid.isEmpty(_axis.options.source.static.data)) {
        var _static = _axis.options.source.static;
        if(_static.data instanceof Array) {
          _axis._data = _static.data;
        }

        _axis.$right.append(_func._joinNodes());

        typeof cb == "function" && cb(_static.data);

        typeof _static.success == "function" && _static.success(rs);
      } else {
        var _dynamic = _axis.options.source.dynamic;

        rapid.ajax({
          url: _dynamic.url,
          data: _dynamic.params,
          success: function(rs) {
            if(rs && rs instanceof Array && rs.length > 0) {
              _axis._data = rs;

              _axis.$right.append(_func._joinNodes());

              typeof cb == "function" && cb(rs);
            }

            typeof _dynamic.success == "function" && _dynamic.success(rs);
          }
        });
      }
    }

    return _axis;
  };

  window.Axis.prototype.render = function() {
    var _this = this;

    _this.create();
    _this.load(function(rs) {
      _this.$obj.append(_this.$element);
    });

    return _this;
  };

  window.Axis.prototype.refresh = function() {
    var _this = this;

    _this.destory();
    _this.render();

    return _this;
  };

  window.Axis.prototype.destory = function() {
    var _this = this;

    _this.$obj.html("");
    _this = null;
  };

  window.Axis.prototype.settings = function(options) {
    var _this = this;

    _this.options = _this._options = $.extend(true, {}, _this._options, options);

    return _this;
  }
})()